package com.bub.pay.api.controller;

import com.alibaba.fastjson.JSON;
import com.bub.pay.api.entity.dto.systemmanagement.AccountInformationDTO;
import com.bub.pay.api.entity.dto.systemmanagement.SysContactInformationDTO;
import com.bub.pay.api.entity.dto.systemmanagement.SysKvPairDTO;
import com.bub.pay.api.entity.vo.systemmanagement.*;
import com.bub.pay.api.service.SystemManagementService;
import com.bub.pay.core.entity.domain.*;
import com.bub.pay.core.entity.vo.merchant.BindIpVo;
import com.bub.pay.core.entity.vo.merchant.QueryIpWhiteVO;
import com.bub.pay.core.enums.DeleteFlagEnum;
import com.bub.pay.core.manager.loginWhite.UserLoginWhiteManager;
import com.bub.pay.core.manager.role.RoleManager;
import com.bub.pay.core.manager.system.SysContactInformationManager;
import com.bub.pay.core.manager.system.SysKvPairEntryManager;
import com.bub.pay.core.manager.user.UserManager;
import com.bub.pay.core.manager.user.role.UserRoleManager;
import com.bub.pay.framework.common.base.Cause;
import com.bub.pay.framework.common.base.Module;
import com.bub.pay.framework.common.entity.model.SessionModel;
import com.bub.pay.framework.common.exception.GlobalException;
import com.bub.pay.framework.common.util.*;
import com.bub.pay.framework.redis.RedisClient;
import com.bub.pay.framework.redis.RedisKeyPrefix;
import com.bub.pay.framework.wrap.annotation.SysLog;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tk.mybatis.mapper.entity.Example;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author chenchen
 * @Description 系统管理
 * @Date 2019/9/4
 */
@RestController
@RequestMapping("/admin/systemManagement/")
public class SystemManagementController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(SystemManagementController.class);
    @Autowired
    private UserManager userManager;
    @Autowired
    private RoleManager roleManager;
    @Autowired
    private UserRoleManager userRoleManager;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private SystemManagementService systemManagementService;
    @Autowired
    private SysKvPairEntryManager sysKvPairEntryManager;
    @Autowired
    private SysContactInformationManager sysContactInformationManager;
    @Autowired
    private UserLoginWhiteManager userLoginWhiteManager;



    /**
     * @Description 账户信息:查询
     * @return 当前用户基本信息
     */
    @SysLog("账户信息:查询")
    @RequiresPermissions("systemManage:accountInfo:list")
    @PostMapping("accountInformation/get")
    public Object getAccountInformation(){
        SessionModel sessionModel = ContextHolder.currentUserInfo();
        //根据用户ID查询当前用户
        SysUser sysUser  = userManager.getById(sessionModel.getUserId());
        AccountInformationDTO informationVo = new AccountInformationDTO();
        BeanUtils.copyProperties(sysUser,informationVo);
        //根据用户id查询角色ID
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setUserId(sessionModel.getUserId());
        SysUserRole sysUserRoleEntity = userRoleManager.getOne(sysUserRole);
        //根据角色ID查询角色名称
        SysRole sysRole =roleManager.getById(sysUserRoleEntity.getRoleId());

        informationVo.setRoleName(sysRole.getName());
        informationVo.setPassword("******");

        return informationVo;
    }

    /**
     * @Description 账户信息:修改-密码和邮箱
     * @return 成功条数
     */
    @SysLog("账户信息:修改-密码和邮箱")
    @RequiresPermissions("systemManage:accountInfo:update")
    @PostMapping("accountInformation/update")
    public Object updateAccountInformation(@RequestBody @Valid AccountInformationVO accountInformationVO){
        SessionModel sessionModel = ContextHolder.currentUserInfo();
        //判断谷歌验证码是否正确
        boolean googleCodeResult = !GoogleAuthenticator.check_code(sessionModel.getGoogleSecret(),
                StrUtil.getGoogleCode(accountInformationVO.getGoogleVerificationCode()),
                System.currentTimeMillis());
        if(googleCodeResult){
            throw new GlobalException(Module.admin, Cause.error_google_secret_code);
        }
        SysUser sysUser = new SysUser();
        int i ;
        switch(accountInformationVO.getTypeUpdate()){
            case "1" : //修改邮箱
                //邮箱和邮箱验证码不能为空
                if(StringUtils.isEmpty(accountInformationVO.getNewEmail())||StringUtils.isEmpty(accountInformationVO.getEmailVerificationCode())){
                    throw new GlobalException(Module.admin, Cause.update_user_email_and_email_code_is_null);
                }
               //判断邮箱验证码是否过期
                String emailKey = RedisKeyPrefix.USER+":updateEmailVerificationCode"+sessionModel.getUserId();
                if(Objects.isNull(redisClient.get(emailKey))){
                    throw new GlobalException(Module.admin, Cause.update_user_email_and_email_code_is_expired);
                }
                //判断邮箱验证码是否正确
                if(!Objects.equals(redisClient.get(emailKey),accountInformationVO.getEmailVerificationCode())){
                    throw new GlobalException(Module.admin, Cause.update_user_email_and_email_code_is_error);
                }
                redisClient.delete(emailKey);
                sysUser.setEmail(accountInformationVO.getNewEmail());
                break;
            case "2" ://修改密码
                //判断新密码和重复密码不能为空
                if(StringUtils.isEmpty(accountInformationVO.getNewPassword())||StringUtils.isEmpty(accountInformationVO.getRepeatPassword())){
                    throw new GlobalException(Module.admin, Cause.update_user_password_new_and_repeat_pwd_is_null);
                }
                //判断新密码和重复密码是否一致
                if(!Objects.equals(accountInformationVO.getNewPassword(),accountInformationVO.getRepeatPassword())){
                    throw new GlobalException(Module.admin, Cause.update_user_password_new_and_repeat_pwd_is_not_same);
                }
                //判断密码是否正确
                boolean passwordSate = !EncryptionUtil.matches(accountInformationVO.getCurrentPassword(),sessionModel.getUserPassword());
                if(passwordSate){
                    throw new GlobalException(Module.admin, Cause.update_user_password_is_incorrect);
                }
                sysUser.setPassword(EncryptionUtil.encode().encode(accountInformationVO.getNewPassword()));
                break;
            case "3" ://修改姓名
                if(StringUtils.isEmpty(accountInformationVO.getNickName())){
                    throw new GlobalException(Module.admin, Cause.update_user_name_is_null);
                }
                sysUser.setNickName(accountInformationVO.getNickName());

            default :
        }
        //修改
        Example example = new Example(SysUser.class);
        example.createCriteria().andEqualTo("id",sessionModel.getUserId());
        i = userManager.updateByExampleSelective(sysUser,example);
        if(i!=1){
            throw new GlobalException(Module.admin, Cause.update_user_password_email_fail);
        }
        return i;
    }

    /**
     * @Description 账户信息:发送邮件:修改邮箱验证码
     * @return
     */
    @SysLog("账户信息:发送邮件:修改邮箱验证码")
    @PostMapping("sendEmailVerificationCode")
    public Object sendEmailVerificationCode(@RequestBody @Valid SendEmailVO sendEmailVO){
        systemManagementService.sendEmailVerificationCode(sendEmailVO,ContextHolder.currentUserInfo());
        return null;
    }


    /**
     * @Description 系统参数设置:分页查询
     * @return
     */
    @SysLog("系统参数设置:分页查询")
    @RequiresPermissions("systemManage:systemParam:list")
    @PostMapping("sysKvPairEntryMsg/get")
    public Object getSysKvPairEntryMsg(@RequestBody SysKvPairEntryVO sysKvPairVO){
        PageHelper.startPage(sysKvPairVO.getPageNo(),sysKvPairVO.getPageSize());

        Example example = new Example(SysKvPairEntry.class);
        Example.Criteria criteria = example.createCriteria();

        if(StringUtils.isNotEmpty(sysKvPairVO.getBaseKey())){
            criteria.andEqualTo("baseKey",sysKvPairVO.getBaseKey());
        }

        if(StringUtils.isNotEmpty(sysKvPairVO.getBaseValue())){
            criteria.andEqualTo("baseValue",sysKvPairVO.getBaseValue());
        }
        example.orderBy("createDate").desc();
        List<SysKvPairEntry> pageList = sysKvPairEntryManager.getByExample(example);
        logger.info("总管理|系统参数设置:分页查询|结果{}", JSON.toJSONString(pageList));
        List<SysKvPairDTO> listDto = new ArrayList<>();
        if(!CollectionUtil.isNullOrEmpty(pageList)){
            listDto =  pageList.stream().map(e->{
                SysKvPairDTO dto = new SysKvPairDTO();
                BeanUtils.copyProperties(e,dto);
                return dto;
            }).collect(Collectors.toList());
        }

        return new PageInfo<>(listDto);
    }

    /**
     * @Description 系统参数设置:修改
     * @return
     */
    @SysLog("系统参数设置:修改")
    @RequiresPermissions("systemManage:systemParam:update")
    @PostMapping("sysKvPairEntryMsg/update")
    public Object updateSysKvPairEntryMsg(@RequestBody @Valid SysKvPairUpdateVO sysKvPairVO){
        SysKvPairEntry sysKvPair = new SysKvPairEntry();
        sysKvPair.setBaseKey(sysKvPairVO.getBaseKey());
        sysKvPair.setDelFlag(false);
        if(sysKvPairEntryManager.getCount(sysKvPair)==0){
            throw new GlobalException(Module.admin, Cause.update_sys_kv_pair_key_not_exist);
        }
        Example example = new Example(SysKvPairEntry.class);
        example.createCriteria().andEqualTo("baseKey",sysKvPairVO.getBaseKey());
        SysKvPairEntry sysKvPairEntry = new SysKvPairEntry();
        sysKvPairEntry.setBaseValue(sysKvPairVO.getBaseValue());
        sysKvPairEntry.setRemarks(sysKvPairVO.getRemarks());
        int i = sysKvPairEntryManager.updateByExampleSelective(sysKvPairEntry,example);
        if(i!=1){
            throw new GlobalException(Module.admin, Cause.update_sys_kv_pair_fail);
        }
        return i;
    }

    /**
     * @Description 客服管理:查询
     * @return
     */
    @SysLog("客服管理:查询")
    @RequiresPermissions("systemManage:customerService:list")
    @PostMapping("sysContactInformation/get")
    public Object getSysContactInformation(){
        Example example = new Example(SysContactInformation.class);
        List<SysContactInformation> list = sysContactInformationManager.getByExample(example);
        List<SysContactInformationDTO> listDto = new ArrayList<>();
        if(!CollectionUtil.isNullOrEmpty(list)){
            listDto = list.stream().map(e->{
                SysContactInformationDTO dto = new SysContactInformationDTO();
                BeanUtils.copyProperties(e,dto);
                return dto;
            }).collect(Collectors.toList());
        }
        return listDto;
    }

    /**
     * @Description 客服管理:修改
     * @return
     */
    @SysLog("客服管理:修改")
    @RequiresPermissions("systemManage:customerService:update")
    @PostMapping("sysContactInformation/update")
    public Object updateSysContactInformation(@RequestBody @Valid SysContactInformationUpdateVO updateVO){
        SysContactInformation informationVo = new SysContactInformation();
        informationVo.setTypeName(updateVO.getTypeName());
        informationVo.setDelFlag(false);
        if(Objects.isNull(sysContactInformationManager.getOne(informationVo))){
            throw new GlobalException(Module.admin, Cause.update_contact_information_does_not_exist);
        }
        Example example = new Example(SysContactInformation.class);
        example.createCriteria().andEqualTo("typeName",updateVO.getTypeName())
                .andEqualTo("delFlag",false);
        SysContactInformation sysContactInformation = new SysContactInformation();
        sysContactInformation.setContactInformation(updateVO.getContactInformation());
        int i = sysContactInformationManager.updateByExampleSelective(sysContactInformation,example);
        if(i!=1){
            throw new GlobalException(Module.admin, Cause.update_sys_kv_pair_fail);
        }
        return i;
    }

    /**
     * @Description 系统日志:分页查询
     * @return
     */
    @SysLog("系统日志:分页查询")
    @RequiresPermissions("systemManage:systemLog:list")
    @PostMapping("sysLogMsg/get")
    public Object getSysLogMsg(@RequestBody SysLogVO sysLogVO){
        return systemManagementService.getSysLogMsg(sysLogVO);
    }


    @RequiresPermissions("systemManage:loginWhiteList:add")
    @SysLog("添加绑定ip")
    @PostMapping("/addLoginIp")
    public Object addLoginIp(@RequestBody @Valid BindIpVo vo) throws Exception{
        //获取当前登录用户
        SessionModel sessionModel = ContextHolder.currentUserInfo();
        UserLoginWhite white = new UserLoginWhite();
        white.setExtendId(sessionModel.getExtendId());
        white.setUserType(sessionModel.getUserType());
        white.setIp(vo.getIp());
        white.setRemarks(vo.getRemarks());
        white.setState(1);
        white.setCreateName(sessionModel.getNickName());
        white.setDelFlag(DeleteFlagEnum.using.flag);
        white.setCreateId(sessionModel.getUserId());
        white.setCreateDate(new Date());
        white.setUpdateId(sessionModel.getUserId());
        white.setUpdateDate(new Date());
        return userLoginWhiteManager.addLoginIp(Module.merchant,white);
    }

    @RequiresPermissions("systemManage:loginWhiteList:list")
    @SysLog("查询用户登录ip")
    @PostMapping("/getLoginIp")
    public Object queryLoginIp(@RequestBody QueryIpWhiteVO vo) throws Exception {

        return userLoginWhiteManager.queryLoginIp(vo);
    }

    @RequiresPermissions("systemManage:loginWhiteList:delete")
    @SysLog("删除用户登录ip,id:$(#map['id'])")
    @PostMapping("/delLoginIp")
    public Object delLoginIp(@RequestBody Map<String, Long> map){
        Long id = null;
        if (!map.containsKey("id") && map.get("id") == null){
            throw new GlobalException(Module.merchant, Cause.params_fail);
        }
        id = map.get("id");
        return userLoginWhiteManager.deleteUserLoginIp(id);
    }



}
